package com.example.aidlservicedemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

/**
 * BinderPoolService 类用于管理多种 Binder 服务，通过 Binder 池提供不同类型的 Binder 实例。
 * 用户可以根据不同的 binderCode 从 Binder 池中获取对应的 Binder 服务。
 *
 * @author 猿小蔡
 * @since 2025/6/28
 */
public class BinderPoolService extends Service {

    /**
     * 日志标签，用于在日志中标识 BinderPoolService 相关的日志信息。
     */
    private static final String TAG = "BinderPoolService";

    /**
     * Binder 池实例，用于根据 binderCode 查询对应的 Binder 服务。
     * 该字段被声明为 final，确保其引用不可变。
     */
    private final IBinderPool.Stub binderPool = new IBinderPoolImpl();

    /**
     * 当客户端调用 bindService() 方法绑定到该服务时，系统会调用此方法。
     *
     * @param intent 客户端传递的 Intent 对象，用于描述绑定请求。
     * @return 返回 Binder 池实例，供客户端与服务进行通信。
     */
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        return binderPool;
    }

    /**
     * IBinderPoolImpl 类实现了 IBinderPool 接口，用于根据 binderCode 查询对应的 Binder 服务。
     */
    private static class IBinderPoolImpl extends IBinderPool.Stub {

        /**
         * 根据传入的 binderCode 查询对应的 Binder 服务。
         *
         * @param binderCode 用于标识不同 Binder 服务的代码。
         * @return 返回对应 binderCode 的 Binder 服务实例，如果未找到则返回 null。
         */
        @Override
        public IBinder queryBinder(int binderCode) {
            Log.d(TAG, "queryBinder: " + binderCode);
            IBinder binder = null;
            switch (binderCode) {
                case BinderCodes.BINDER_COMPUTE:
                    binder = new IComputeImpl();
                    break;
                case BinderCodes.BINDER_LOCATION:
                    binder = new ILocationServiceImpl();
                    break;
                case BinderCodes.BINDER_SECURITY:
                    binder = new ISecurityServiceImpl();
                    break;
                default:
                    Log.w(TAG, "Unknown binder code: " + binderCode);
            }
            return binder;
        }

    }

    /**
     * IComputeImpl 类实现了 ICompute 接口，提供基本的计算服务。
     */
    private static class IComputeImpl extends ICompute.Stub {

        /**
         * 实现两个整数相加的功能。
         *
         * @param a 第一个整数。
         * @param b 第二个整数。
         * @return 两个整数相加的结果。
         */
        @Override
        public int add(int a, int b) {
            Log.d(TAG, "Compute add: " + a + " + " + b);
            return a + b;
        }

        /**
         * 实现两个整数相乘的功能。
         *
         * @param a 第一个整数。
         * @param b 第二个整数。
         * @return 两个整数相乘的结果。
         */
        @Override
        public int multiply(int a, int b) {
            Log.d(TAG, "Compute multiply: " + a + " * " + b);
            return a * b;
        }

    }

    /**
     * ILocationServiceImpl 类实现了 ILocationService 接口，提供定位相关服务。
     */
    private static class ILocationServiceImpl extends ILocationService.Stub {

        /**
         * 模拟的当前位置信息，默认值为 "Unknown"。
         */
        private String mockLocation = "Unknown";

        /**
         * 获取当前模拟的位置信息。
         *
         * @return 当前模拟的位置信息。
         */
        @Override
        public String getCurrentLocation() {
            Log.d(TAG, "getCurrentLocation");
            return mockLocation;
        }

        /**
         * 设置模拟的位置信息。
         *
         * @param location 要设置的模拟位置信息。
         */
        @Override
        public void setMockLocation(String location) {
            Log.d(TAG, "setMockLocation: " + location);
            mockLocation = location;
        }

    }

    /**
     * ISecurityServiceImpl 类实现了 ISecurityService 接口，提供简单的加密和解密服务。
     */
    private static class ISecurityServiceImpl extends ISecurityService.Stub {

        /**
         * 加密和解密使用的密钥。
         */
        private static final String KEY = "BinderKey";

        /**
         * 对输入的内容进行简单加密。
         *
         * @param content 要加密的内容。
         * @return 加密后的字符串。
         */
        @Override
        public String encrypt(String content) {
            Log.d(TAG, "encrypt: " + content);
            // 简单加密逻辑（实际应用中应使用更安全的算法）
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < content.length(); i++) {
                sb.append((char) (content.charAt(i) ^ KEY.charAt(i % KEY.length())));
            }
            return sb.toString();
        }

        /**
         * 对输入的密码进行解密，解密逻辑与加密相同。
         *
         * @param password 要解密的密码。
         * @return 解密后的字符串。
         */
        @Override
        public String decrypt(String password) {
            Log.d(TAG, "decrypt: " + password);
            // 解密逻辑（与加密相同）
            return encrypt(password);
        }

    }

}
